package top.fullj.chase.plugin

import com.android.build.gradle.AppPlugin
import com.android.build.gradle.LibraryPlugin
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.tasks.compile.JavaCompile

class ChasePlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        //android application
        def hasApp = project.plugins.withType(AppPlugin)
        //android library
        def hasLib = project.plugins.withType(LibraryPlugin)

        final def log = project.logger

        project.dependencies {
            implementation 'org.aspectj:aspectjrt:1.9.7'
        }

        project.extensions.create('chase', ChaseExtension)

        if (project.hasProperty("android")) {
            final def variants = hasApp ? project.android.applicationVariants
                    : project.android.libraryVariants
            variants.all { variant ->
                JavaCompile javaCompile = variant.javaCompileProvider.get()

                if (!project.chase.enabled && !variant.buildType.isDebuggable()) {
                    log.info("Chase for android is disabled in non-debug build " + javaCompile.name)
                    return
                }

                javaCompile.doLast {
                    log.info("Chase for android start ajc after " + javaCompile.name)
                    ajc(log, javaCompile, project.android.bootClasspath.join(File.pathSeparator))
                }
            }
        } else {
            JavaCompile javaCompile = project.tasks.compileJava
            javaCompile.doLast {
                if (project.chase.enabled) {
                    log.info("Chase for java start ajc after " + javaCompile.name)
                    ajc(log, javaCompile, null)
                } else {
                    log.info("Chase for java is disabled in build " + javaCompile.name)
                }
            }
        }
    }

    private static void ajc(Logger log, JavaCompile javaCompile, String bootclasspath) {
        String[] args = [
                "-showWeaveInfo",
                "-1.6",
                "-inpath", javaCompile.destinationDir.toString(),
                "-aspectpath", javaCompile.classpath.asPath,
                "-d", javaCompile.destinationDir.toString(),
                "-classpath", javaCompile.classpath.asPath,
                "-bootclasspath", bootclasspath
        ]
        if (bootclasspath == null) {
            args = args[0..(args.length - 3)]
        }

        log.info "Chase ajc args: " + Arrays.toString(args)

        MessageHandler handler = new MessageHandler(true)
        new Main().run(args, handler)
        for (IMessage message : handler.getMessages(null, true)) {
            switch (message.getKind()) {
                case IMessage.ABORT:
                case IMessage.ERROR:
                case IMessage.FAIL:
                    log.error message.message, message.thrown
                    break
                case IMessage.WARNING:
                    log.warn message.message, message.thrown
                    break
                case IMessage.INFO:
                    log.info message.message, message.thrown
                    break
                case IMessage.DEBUG:
                    log.debug message.message, message.thrown
                    break
            }
        }
    }

}